package com.cloud.force.api.service.impl;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloud.force.api.bean.MenuTabAuthority;
import com.cloud.force.api.bean.Part;
import com.cloud.force.api.bean.TabMenuHeader;
import com.cloud.force.api.entity.TabPart;
import com.cloud.force.api.entity.TaskListTab;
import com.cloud.force.api.entity.TaskListTabGroup;
import com.cloud.force.api.mapper.TabPartMapper;
import com.cloud.force.api.mapper.TaskListTabGroupMapper;
import com.cloud.force.api.mapper.TaskListTabMapper;
import com.cloud.force.api.service.TaskListTabService;
import com.cloud.force.common.result.QkIcon;
import com.cloud.force.common.result.QkTreeNode;
import com.cloud.force.common.utils.RedisKeyHelper;

import tk.mybatis.mapper.entity.Example;

@Service
@Transactional
public class TaskListTabServiceImpl implements TaskListTabService {
	@Autowired
	private TaskListTabGroupMapper taskListTabGroupMapper;
	@Autowired
	private TaskListTabMapper taskListTabMapper;
	@Autowired
	private TabPartMapper tabPartMapper;
	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Override
	public List<QkTreeNode> listTree() {
		Example grpExample = new Example(TaskListTabGroup.class);
		Example.Criteria grpCriteria = grpExample.createCriteria();
		grpCriteria.andEqualTo("deleteFlag", 0);
		grpExample.orderBy("displayOrder").asc();
		List<TaskListTabGroup> groups = taskListTabGroupMapper.selectByExample(grpExample);
		Example tabExample = new Example(TaskListTab.class);
		Example.Criteria tabCriteria = tabExample.createCriteria();
		tabCriteria.andEqualTo("deleteFlag", 0);
		tabExample.orderBy("displayOrder").asc();
		List<TaskListTab> tabs = taskListTabMapper.selectByExample(tabExample);
		List<QkTreeNode> nodes = new ArrayList<QkTreeNode>();
		for (TaskListTabGroup group : groups) {
			QkTreeNode grpNode = new QkTreeNode("grp_" + group.getGroupId(), group.getGroupName());
			grpNode.setCollapsedIcon(QkIcon.FA_FOLDER);
			grpNode.setExpandedIcon(QkIcon.FA_FOLDER_OPEN);
			grpNode.setRootFlag(true);
			grpNode.setSelectable(true);
			for (TaskListTab tab : tabs) {
				if (tab.getGroupId().equals(group.getGroupId())) {
					QkTreeNode menuNode = new QkTreeNode(tab.getTabId(), tab.getTabName());
					menuNode.setSeniorId("grp_" + group.getGroupId());
					menuNode.setSelectable(true);
					menuNode.setLeaf(true);
					menuNode.setIcon(QkIcon.FA_LAPTOP);
					grpNode.getChildren().add(menuNode);
				}
			}
			nodes.add(grpNode);
		}
		return nodes;
	}

	@Override
	public List<TabMenuHeader> listTaskListTabHeader() {
		Example grpExample = new Example(TaskListTabGroup.class);
		Example.Criteria grpCriteria = grpExample.createCriteria();
		grpCriteria.andEqualTo("deleteFlag", 0);
		grpExample.orderBy("displayOrder").asc();
		List<TaskListTabGroup> groups = taskListTabGroupMapper.selectByExample(grpExample);
		Example tabExample = new Example(TaskListTab.class);
		Example.Criteria tabCriteria = tabExample.createCriteria();
		tabCriteria.andEqualTo("deleteFlag", 0);
		tabExample.orderBy("displayOrder").asc();
		List<TaskListTab> tabs = taskListTabMapper.selectByExample(tabExample);

		List<TabMenuHeader> results = new ArrayList<TabMenuHeader>();
		for (TaskListTabGroup grp : groups) {
			TabMenuHeader father = new TabMenuHeader();
			father.setId(grp.getGroupId());
			father.setHeader(grp.getGroupName());
			father.setField(grp.getGroupName());
			for (TaskListTab tab : tabs) {
				if (tab.getGroupId().equals(grp.getGroupId())) {
					TabMenuHeader child = new TabMenuHeader();
					child.setId(tab.getTabId());
					child.setHeader(tab.getTabName());
					child.setField(tab.getTabId() + "");
					child.setWidth(100);
					father.getChildren().add(child);
				}
			}
			if (father.getChildren().size() > 0) {
				father.setWidth(father.getChildren().size() * 100);
				results.add(father);
			}
		}
		return results;
	}

	@Override
	public void saveUpdatePartAuth(List<MenuTabAuthority> parts, long actDefId, long taskListId) {
		Example exp = new Example(TabPart.class);
		Example.Criteria criteria = exp.createCriteria();
		criteria.andEqualTo("taskListId", taskListId);
		criteria.andEqualTo("actDefId", actDefId);
		tabPartMapper.deleteByExample(exp);
		List<TabPart> partTabs = new ArrayList<TabPart>();
		for (MenuTabAuthority part : parts) {
			TabPart tPart = new TabPart();
			tPart.setTaskListId(taskListId);
			tPart.setActDefId(actDefId);
			tPart.setPartId(part.getPartId());
			tPart.setTabId(part.getMenuTabId());
			tPart.setAuthCode(part.getCode());
			partTabs.add(tPart);
		}
		final List<TabPart> pts = partTabs;
		jdbcTemplate.batchUpdate(
				"insert into tab_part(task_list_id, act_def_id, part_id, tab_id, auth_code) values (?, ?, ?, ?, ?)",
				new BatchPreparedStatementSetter() {
					@Override
					public void setValues(PreparedStatement ps, int i) throws SQLException {
						TabPart p = pts.get(i);
						ps.setLong(1, p.getTaskListId());
						ps.setLong(2, p.getActDefId());
						ps.setLong(3, p.getPartId());
						ps.setLong(4, p.getTabId());
						ps.setInt(5, p.getAuthCode());
					}

					@Override
					public int getBatchSize() {
						return pts.size();
					}
				});

	}

	@Override
	public List<Part> listPartAuthority(long taskListId, long actDefId, List<Part> parts) {
		Example example = new Example(TaskListTab.class);
		example.orderBy("displayOrder").asc();
		List<TaskListTab> tabs = taskListTabMapper.selectByExample(example);
		// 先设置所有的tab为默认权限
		for (Part p : parts) {
			for (TaskListTab tab : tabs) {
				p.getAuths().put(tab.getTabId(), tab.getDefaultAuth());
			}
		}
		// 设置所有参与者配置的权限
		Example tabPartsExample = new Example(TabPart.class);
		Example.Criteria tpCriteria = tabPartsExample.createCriteria();
		tpCriteria.andEqualTo("taskListId", taskListId);
		tpCriteria.andEqualTo("actDefId", actDefId);
		List<TabPart> tabParts = tabPartMapper.selectByExample(tabPartsExample);

		// 配置权限覆盖默认权限
		for (Part p : parts) {
			Map<Long, Integer> auths = p.getAuths();
			for (TabPart tp : tabParts) {
				if (tp.getPartId().equals(p.getPartId())) {
					auths.put(tp.getTabId(), tp.getAuthCode());
				}
			}
		}
		return parts;
	}

	@Override
	public List<TaskListTab> listTaskListPartByPart(long taskListId, long actDefId, List<Long> parts) {
		Example example = new Example(TabPart.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("taskListId", taskListId);
		criteria.andEqualTo("actDefId", actDefId);
		criteria.andIn("partId", parts);
		List<TabPart> tabParts = tabPartMapper.selectByExample(example);
		List<Long> tabIds = new ArrayList<Long>();
		for (TabPart tp : tabParts) {
			tabIds.add(tp.getTabId());
		}
		if (tabIds.size() > 0) {
			Example tabExample = new Example(TaskListTab.class);
			Example.Criteria tabCriteria = tabExample.createCriteria();
			tabCriteria.andIn("tabId", tabIds);
			tabExample.orderBy("displayOrder");
			return taskListTabMapper.selectByExample(tabExample);
		}
		return null;
	}

	@Override
	public TaskListTabGroup saveUpdateGroup(TaskListTabGroup group) {
		if (null == group.getGroupId() || 0 == group.getGroupId()) {
			long groupId = group.getGroupId();
			group.setDeleteFlag(0);
			group.setDisplayOrder((int) groupId);
			taskListTabGroupMapper.insert(group);
		} else {
			group.setDeleteFlag(0);
			taskListTabGroupMapper.updateByPrimaryKey(group);
		}
		return group;
	}

	@Override
	public void deleteGroup(long groupId) {
		TaskListTabGroup group = taskListTabGroupMapper.selectByPrimaryKey(groupId);
		group.setDeleteFlag(1);
		taskListTabGroupMapper.updateByPrimaryKey(group);
	}

	@Override
	public TaskListTab saveUpdateTaskListTab(TaskListTab tab) {
		if (null == tab.getTabId() || 0 == tab.getTabId()) {
			tab.setDeleteFlag(0);
			taskListTabMapper.insert(tab);
		} else {
			tab.setDeleteFlag(0);
			taskListTabMapper.updateByPrimaryKey(tab);
		}
		return tab;
	}

	@Override
	public long deleteTab(long tabId) {
		TaskListTab tab = taskListTabMapper.selectByPrimaryKey(tabId);
		tab.setDeleteFlag(1);
		taskListTabMapper.updateByPrimaryKey(tab);
		return tabId;
	}

	@Override
	public TaskListTab loadTab(long tabId) {
		return taskListTabMapper.selectByPrimaryKey(tabId);
	}

}
